import {
    ol
} from '../constants'
import mix from '../utils/mixin'
import Style from '../style/Style'

class Layer extends mix(Style) {
    constructor(map) {
        super();
        this.map = map || null;
        if (!this.map) {
            throw new Error('缺少地图对象！')
        }
    }

    /**
     * 通过layerName获取图层
     * @param layerName
     * @returns {*}
     */
    getLayerByLayerName(layerName) {
        try {
            let targetLayer = null;
            if (this.map) {
                let layers = this.map.getLayers().getArray();

                targetLayer = this.getLayerInternal(layers, 'layerName', layerName)
            }
            return targetLayer;
        } catch (e) {
            console.log(e);
        }
    }

    /**
     * 内部处理获取图层方法
     * @param layers
     * @param key
     * @param value
     * @returns {*}
     */
    getLayerInternal(layers, key, value) {
        let _target = null
        if (layers.length > 0) {
            layers.every(layer => {
                if (layer instanceof ol.layer.Group) {
                    let layers = layer.getLayers().getArray()
                    _target = this.getLayerInternal(layers, key, value)
                    if (_target) {
                        return false
                    } else {
                        return true
                    }
                } else if (layer.get(key) === value) {
                    _target = layer
                    return false
                } else {
                    return true
                }
            })
        }
        return _target
    }

    /**
     * 通过键名键值获取图层集合（注意键名键值必须是set(key, value)）
     * @param key
     * @param value
     */
    getLayersArrayByKeyValue(key, value) {
        try {
            let targetLayers = []
            if (this.map) {
                let layers = this.map.getLayers().getArray()
                targetLayers = this.getLayersArrayInternal(layers, key, value)
            }
            return targetLayers
        } catch (e) {
            console.log(e)
        }
    }
    /**
     * 根据相关键值键名获取图层集合
     * @param layers
     * @param key
     * @param value
     * @returns {Array}
     */
    getLayersArrayInternal(layers, key, value) {
        let _target = []
        if (layers.length > 0) {
            layers.forEach(layer => {
                if (layer instanceof ol.layer.Group) {
                    let layers = layer.getLayers().getArray()
                    let _layer = this.getLayersArrayInternal(layers, key, value)
                    if (_layer) {
                        _target = _target.concat(_layer)
                    }
                } else if (layer.get(key) === value) {
                    _target.push(layer)
                }
            })
        }
        return _target
    }
    /**
  * 通过要素获取图层
  * @param feature
  * @returns {*}
  */
    getLayerByFeatuer(feature) {
        let tragetLayer = null
        if (this.map) {
            if (feature instanceof ol.Feature) {
                let layers = this.map.getLayers().getArray()
                layers.every(layer => {
                    if (layer && layer instanceof ol.layer.Vector && layer.getSource) {
                        let source = layer.getSource()
                        if (source.getFeatures) {
                            let features = source.getFeatures()
                            features.every(feat => {
                                if (feat === feature) {
                                    tragetLayer = layer
                                    return false
                                } else {
                                    return true
                                }
                            })
                        }
                        return false
                    } else if (layer && layer instanceof ol.layer.Group) {
                        let layers = layer.getLayers().getArray()
                        layers.every(layer => {
                            if (layer && layer instanceof ol.layer.Vector && layer.getSource) {
                                let source = layer.getSource()
                                if (source.getFeatures) {
                                    let features = source.getFeatures()
                                    features.every(feat => {
                                        if (feat === feature) {
                                            tragetLayer = layer
                                            return false
                                        } else {
                                            return true
                                        }
                                    })
                                }
                                return true
                            } else {
                                return true;
                            }
                        })
                    }
                    else {


                        return true
                    }
                })
            } else {
                throw new Error('传入的不是要素!')
            }
        }
        return tragetLayer
    }

    /**
     * 创建临时图层
     * @param layerName
     * @param params
     * @returns {*}
     */
    creatVectorLayer(layerName, params) {
        try {
            if (this.map) {
                let vectorLayer = this.getLayerByLayerName(layerName);
                if (!(vectorLayer instanceof ol.layer.Vector)) {
                    vectorLayer = null;
                }
                if (!vectorLayer) {
                    if (params && params.create) {
                        vectorLayer = new ol.layer.Vector({
                            layerName: layerName,
                            params: params,
                            layerType: 'vector',
                            source: new ol.source.Vector({
                                wrapX: false
                            }),
                            style: new ol.style.Style({
                                fill: new ol.style.Fill({
                                    color: 'rgba(67, 110, 238, 0.4)'
                                }),
                                stroke: new ol.style.Stroke({
                                    color: '#4781d9',
                                    width: 2
                                }),
                                image: new ol.style.Circle({
                                    radius: 7,
                                    fill: new ol.style.Fill({
                                        color: '#ffcc33'
                                    })
                                })
                            })
                        });
                    }
                }
                if (this.map && vectorLayer) {
                    if (params && params.hasOwnProperty('selectable')) {
                        vectorLayer.set("selectable", params.selectable);
                    }
                    this.map.addLayer(vectorLayer);
                }
                return vectorLayer;
            }
        } catch (e) {
            console.log(e);
        }
    }

    /**
     * 创建专题图层
     * @param layerName
     * @param params
     * @returns {*}
     */
    creatTitleLayer(layerName, params) {
        let titleLayer = null;
        if (this.map) {
            let serviceUrl = params['serviceUrl'];
            if (!serviceUrl) return null;
            titleLayer = new ol.layer.Tile({
                layerName: layerName,
                layerType: 'title',
                source: new ol.source.TileArcGISRest({
                    url: serviceUrl,
                    params: params,
                    wrapX: false
                }),
                wrapX: false
            });
            this.map.addLayer(titleLayer)
        }
        return titleLayer;
    }

    /**
     * 创建ImageWMSLayer
     * @param layerName
     * @param params
     * @returns {string}
     */
    createImageWMSLayer(layerName, params) {
        let layer = this.getLayerByLayerName(layerName)
        if (!(layer instanceof ol.layer.Image)) {
            layer = null
        } else if ((layer instanceof ol.layer.Image) && !(params['addLayer'] === false)) {
            this.map.removeLayer(layer)
            layer = null
        }
        if (!layer && params && params['layerUrl'] && params['create']) {
            layer = new ol.layer.Image({
                layerName: layerName,
                visible: (params['isVisible'] === false) ? params['isVisible'] : true,
                opacity: (params['opacity'] && (typeof params['opacity'] === 'number')) ? params['opacity'] : 1,
                source: new ol.source.ImageWMS({
                    url: params['layerUrl'],
                    crossOrigin: (params['crossOrigin'] ? params['crossOrigin'] : undefined),
                    params: {
                        LAYERS: params['layers'], // require
                        STYLES: params['style'] ? params['style'] : '',
                        VERSION: params['version'] ? params['version'] : '1.3.0',
                        WIDTH: params['width'] ? params['width'] : 256,
                        HEIGHT: params['height'] ? params['height'] : 256,
                        BBOX: params['bbox'], // require
                        SRS: (params['srs'] ? params['srs'] : 'EPSG:3857'),
                        CRS: (params['srs'] ? params['srs'] : 'EPSG:3857'),
                        REQUEST: params['request'] ? params['request'] : 'GetMap',
                        TRANSPARENT: true,
                        TILED: (params['tiled'] === false) ? params['tiled'] : true,
                        TILESORIGIN: (params['tiledsorrigin'] ? params['tiledsorrigin'] : undefined),
                        SERVICE: 'WMS',
                        FORMAT: (params['format'] ? params['format'] : 'image/png'),
                        VIEWPARAMS: (params['viewparams'] ? params['viewparams'] : '')
                    },
                    serverType: 'geoserver',
                    wrapX: false
                })
            })
        }
        if (this.map && layer && !(params['addLayer'] === false)) {
            this.map.addLayer(layer)
        }
        return layer
    }

    /**
     * 移除图层
     * @param layerName
     */
    removeLayerByLayerName(layerName) {
        if (this.map) {
            let layer = this.getLayerByLayerName(layerName);
            if (layer && layer instanceof ol.layer.Vector && layer.getSource() && layer.getSource().clear) {
                layer.getSource().clear();
            }
        }
    }

}

export default Layer